﻿//using DBUtil.Annotations;
//using DBUtil.Util;
//using System;
//using System.Collections.Generic;
//using System.Data;
//using System.Linq;
//using System.Linq.Expressions;
//using System.Reflection;
//using System.Text;
//using System.Threading.Tasks;

//namespace DBUtil.Builders
//{
//    /// <summary>
//    /// 默认过滤条件过滤器
//    /// </summary>
//    /// <typeparam name="T"></typeparam>
//    public class DefaultWhereBuilder<T> : IWhereBuilder<T> where T : class, new()
//    {
//        private Type _type = null;
//        private DBAccess db = null;
//        private T _data = null;
//        private List<PropertyInfo> _props = null;
//        private readonly Func<string> _getAlias = null;
//        private readonly Func<string> _getTable = null;
//        private readonly Func<T> _getData = null;
//        private IDeleteBuilder<T> _deleteBuilder = null;
//        private IUpdateBuilder<T> _updateBuilder = null;
//        private ISelectBuilder<T> _selectBuilder = null;
//        private int counter = 500;

//        private List<(string type, object data)> _commands = new List<(string type, object data)>();

//        /// <summary>
//        /// 构造函数
//        /// </summary>
//        /// <param name="db"></param>
//        /// <param name="getAlias"></param>
//        /// <param name="getTable"></param>
//        /// <param name="getData"></param>
//        public DefaultWhereBuilder(DBAccess db, Func<string> getAlias, Func<string> getTable, Func<T> getData)
//        {
//            _getAlias = getAlias;
//            _getTable = getTable;
//            _getData = getData;
//            this.db = db;
//            _type = typeof(T);
//            _props = _type.GetProperties().ToList();
//        }

//        public IWhereBuilder<T> And(Expression<Predicate<T>> expression)
//        {
//            _commands.Add((nameof(And), expression));
//            return this;
//        }

//        public IWhereBuilder<T> AndRaw(string filterSql, params IDataParameter[] paras)
//        {
//            _commands.Add((nameof(AndRaw), (filterSql, paras)));
//            return this;
//        }

//        public IDeleteBuilder<T> BackDelete()
//        {
//            return _deleteBuilder;
//        }

//        public ISelectBuilder<T> BackSelect()
//        {
//            return _selectBuilder;
//        }

//        public IUpdateBuilder<T> BackUpdate()
//        {
//            return _updateBuilder;
//        }

//        public (string filterSql, IDataParameter[] paras) Build()
//        {
//            //先获取别名
//            var _alias = _getAlias();
//            if (string.IsNullOrWhiteSpace(_alias))
//            {
//                _alias = _getTable();
//            }
//            //获取模型值
//            _data = _getData();
//            var filterSql = "";
//            var paras = new List<IDataParameter>();
//            //放弃WhereKey之前的命令先合并command
//            for (int i = 0; i < _commands.Count; i++)
//            {
//                var command = _commands[i];
//                if (command.type == nameof(WhereKey))
//                {
//                    //先处理Wherekey
//                    var keys = _getKeys();
//                    Dictionary<string, object> keysParas = new Dictionary<string, object>();
//                    foreach (var key in keys)
//                    {
//                        var colname = "";
//                        var attr = key.GetCustomAttribute<ColumnAttribute>();
//                        if (attr != null && (!string.IsNullOrWhiteSpace(attr.Name)))
//                        {
//                            colname = attr.Name;
//                        }
//                        else
//                        {
//                            colname = key.Name;
//                        }
//                        keysParas.Add(colname, key.GetValue(_data));
//                    }
//                    var (_filter, _paras) = SqlUtil.GenerateFilterSql(db, keysParas, "key_", null);
//                    addFilter(_filter, "and");
//                    paras.AddRange(_paras);
//                }
//                else if (command.type == nameof(And))
//                {
//                    var expresion = (Expression<Predicate<T>>)command.data;
//                    var (_filter, _paras) = ExpressionUtil.GetFilterInfo<T>(expresion);
//                    addFilter(_filter, "and");
//                    paras.AddRange(_paras);
//                }
//                else if (command.type == nameof(AndRaw))
//                {
//                    var (_fitler, _paras) = ((string, IDataParameter[]))command;
//                    if (_fitler.Trim().StartsWith("(")) { }
//                    else
//                    {
//                        _fitler = "(" + _fitler + ")";
//                    }
//                    addFilter(_fitler, "and");
//                    paras.AddRange(_paras);
//                }
//                else if (command.type == nameof(Or))
//                {
//                    var expresion = (Expression<Predicate<T>>)command.data;
//                    var (_filter, _paras) = ExpressionUtil.GetFilterInfo<T>(expresion);
//                    addFilter(_filter, "or");
//                    paras.AddRange(_paras);
//                }
//                else if (command.type == nameof(OrRaw))
//                {
//                    var (_fitler, _paras) = ((string, IDataParameter[]))command;
//                    if (_fitler.Trim().StartsWith("(")) { }
//                    else
//                    {
//                        _fitler = "(" + _fitler + ")";
//                    }
//                    addFilter(_fitler, "or");
//                    paras.AddRange(_paras);
//                }
//            }
//            return (filterSql, paras.ToArray());
//            void addFilter(string filter, string op)
//            {
//                if (string.IsNullOrWhiteSpace(filterSql))
//                {
//                    filterSql += op + " " + filter;
//                }
//                else
//                {
//                    filterSql = " " + filter;
//                }
//            }
//        }

//        public IWhereBuilder<T> Init(IUpdateBuilder<T> builder)
//        {
//            _updateBuilder = builder;
//            return this;
//        }

//        public IWhereBuilder<T> Init(IDeleteBuilder<T> builder)
//        {
//            _deleteBuilder = builder;
//            return this;
//        }

//        public IWhereBuilder<T> Init(ISelectBuilder<T> builder)
//        {
//            _selectBuilder = builder;
//            return this;
//        }

//        public IWhereBuilder<T> Or(Expression<Predicate<T>> expression)
//        {
//            _commands.Add((nameof(Or), expression));
//            return this;
//        }

//        public IWhereBuilder<T> OrRaw(string filterSql, params IDataParameter[] paras)
//        {
//            _commands.Add((nameof(OrRaw), (filterSql, paras)));
//            return this;
//        }

//        public IWhereBuilder<T> WhereKey()
//        {
//            ClearFilters();
//            _commands.Add((nameof(WhereKey), null));
//            return this;
//        }

//        private List<PropertyInfo> _getKeys() => _props.Where(p => p.GetCustomAttribute<KeyAttribute>() != null).ToList();

//        public IWhereBuilder<T> ClearFilters()
//        {
//            _commands.Clear();
//            return this;
//        }
//    }
//}
